# -*- coding: utf-8 -*-
# @Time    : 2024/7/19 17:45
# @Author  : yujiahao
# @File    : 51_fastapi_operationId.py
# @description:从这里往后就是fastapi的高级操作
from typing import Union, Set

from fastapi import FastAPI
from fastapi.routing import APIRoute
from pydantic import BaseModel

app = FastAPI()


# todo 手动指定

# 可以在路径操作中通过参数 operation_id 设置要使用的 OpenAPI operationId。
# 务必确保每个操作路径的 operation_id 都是唯一的。
@app.get("/items/", operation_id="some_specific_id_you_define")
async def read_items():
    return [{"item_id": "Foo"}]


# todo 从 OpenAPI 中排除
@app.get("/items_1/{item_id}", include_in_schema=False)
async def read_item_1(item_id: str):
    return {"item_id": item_id}


# todo 使用 路径操作函数 的函数名作为 operationId
"""
如果你想用你的 API 的函数名作为 operationId 的名字，你可以遍历一遍 API 的函数名，
然后使用他们的 APIRoute.name 重写每个 路径操作 的 operation_id。
你应该在添加了所有 路径操作 之后执行此操作。
"""


def use_route_names_as_operation_ids(app: FastAPI) -> None:
    """
    Simplify operation IDs so that generated API clients have simpler function
    names.

    Should be called only after all routes have been added.
    """
    for route in app.routes:
        if isinstance(route, APIRoute):
            route.operation_id = route.name  # in this case, 'read_items'


# 这里调用就会返回对应路径的函数名字，但是务必呀保证
use_route_names_as_operation_ids(app)

# todo docstring 的高级描述

"""
你可以限制 路径操作函数 的 docstring 中用于 OpenAPI 的行数。

添加一个 \f （一个「换页」的转义字符）可以使 FastAPI 在那一位置截断用于 OpenAPI 的输出。

剩余部分不会出现在文档中，但是其他工具（比如 Sphinx）可以使用剩余部分。
"""


class Item(BaseModel):
    name: str
    description: Union[str, None] = None
    price: float
    tax: Union[float, None] = None
    tags: Set[str] = set()


@app.post("/items/", response_model=Item, summary="Create an item")
async def create_item(item: Item):
    """
    Create an item with all the information:
    \f
    - **name**: each item must have a name
    - **description**: a long description
    - **price**: required
    - **tax**: if the item doesn't have tax, you can omit this
    - **tags**: a set of unique tag strings for this item
    \f
    :param item: User input.
    使用 \f 换页符来截断用于 OpenAPI 文档的 docstring 主要是针对多行注释的情况，因为它的目的是在详细的文档字符串中进行内容分隔。
    然而，单行注释并不适合这种用法，因为单行注释本身就非常简洁，不需要额外的分隔符来控制显示。
    """
    return item
